<template>
    <div class="tags-view-container">
        <div class="scroll-container">
            <v-sheet elevation="6" :theme="activeThemeName">
                <v-tabs next-icon="mdi-arrow-right-bold-box-outline" prev-icon="mdi-arrow-left-bold-box-outline" show-arrows
                    @update:model-value="updateValue" :model-value="tagValue">
                    <router-link :to="{ path: tag.path, query: tag.query }" v-for="tag in tagsViewStore.visitedViews"
                        @contextmenu.prevent="openMenu(tag, $event)" :key="tag.path">
                        <v-tab>
                            <v-icon :size="18" v-if="showTagIcon">{{ tag.meta?.icon }}</v-icon>
                            {{ tag.meta?.title }}
                        </v-tab>
                    </router-link>
                </v-tabs>
            </v-sheet>
        </div>
        <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
            <li @click="refreshSelectedTag(selectedTag)">刷新</li>
            <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭</li>
            <li @click="closeOthersTags">关闭其它</li>
            <li @click="closeAllTags(selectedTag)">关闭所有</li>
        </ul>
    </div>
</template>
<script lang="ts" setup>
import { type RouteRecordRaw, useRoute, useRouter } from "vue-router"
import { type ITagView, useTagsViewStore } from "@/store/modules/tags-view"
import { usePermissionStore } from "@/store/modules/permission"
import { useSettingsStore } from "@/store/modules/setting"
import path from "path-browserify"
import { useTheme } from "@/hooks/useTheme"
import bus from '@/utils/Bus'

const { activeThemeName } = useTheme()


const instance = getCurrentInstance()
const router = useRouter()
const route = useRoute()
const tagsViewStore = useTagsViewStore()
const permissionStore = usePermissionStore()
const settingsStore = useSettingsStore()


const visible = ref(false)
const top = ref(0)
const left = ref(0)
const tagValue = ref(0)
const selectedTag = ref<ITagView>({})
let affixTags: ITagView[] = []

const isActive = (tag: ITagView) => {
    return tag.path === route.path
}

const isAffix = (tag: ITagView) => {
    return tag.meta?.affix
}

const filterAffixTags = (routes: RouteRecordRaw[], basePath = "/") => {
    let tags: ITagView[] = []
    routes.forEach((route) => {
        if (route.meta?.affix) {
            const tagPath = path.resolve(basePath, route.path)
            tags.push({
                fullPath: tagPath,
                path: tagPath,
                name: route.name,
                meta: { ...route.meta }
            })
        }
        if (route.children) {
            const childTags = filterAffixTags(route.children, route.path)
            if (childTags.length >= 1) {
                tags = tags.concat(childTags)
            }
        }
    })
    return tags
}

const initTags = () => {
    affixTags = filterAffixTags(permissionStore.routes)
    for (const tag of affixTags) {
        // 必须含有 name 属性
        if (tag?.name) {
            tagsViewStore.addVisitedView(tag)
        }
    }
}

const addTags = () => {
    if (route?.name) {
        tagsViewStore.addVisitedView(route)
        tagsViewStore.addCachedView(route)
    }
}

const refreshSelectedTag = (view: ITagView) => {
    tagsViewStore.delCachedView(view)
    router.replace({ path: "/redirect" + view.path, query: view.query })
}

const closeSelectedTag = (view: ITagView) => {
    tagsViewStore.delVisitedView(view)
    tagsViewStore.delCachedView(view)
    if (isActive(view)) {
        toLastView(tagsViewStore.visitedViews, view)
    }
}

const closeOthersTags = () => {
    if (selectedTag.value.fullPath !== route.path && selectedTag.value.fullPath !== undefined) {
        router.push(selectedTag.value.fullPath)
    }
    tagsViewStore.delOthersVisitedViews(selectedTag.value)
    tagsViewStore.delOthersCachedViews(selectedTag.value)
}

const closeAllTags = (view: ITagView) => {
    tagsViewStore.delAllVisitedViews()
    tagsViewStore.delAllCachedViews()
    if (affixTags.some((tag) => tag.path === route.path)) {
        return
    }
    toLastView(tagsViewStore.visitedViews, view)
}

const toLastView = (visitedViews: ITagView[], view: ITagView) => {
    const latestView = visitedViews.slice(-1)[0]
    if (latestView !== undefined && latestView.fullPath !== undefined) {
        router.push(latestView.fullPath)
    } else {
        // 如果 TagsView 全部被关闭了，则默认重定向到主页
        if (view.name === "/home") {
            // 重新加载主页
            router.push({ path: "/redirect" + view.path, query: view.query })
        } else {
            router.push("/")
        }
    }
}

const openMenu = (tag: ITagView, e: MouseEvent) => {
    const menuMinWidth = 105
    // container margin left
    const offsetLeft = instance!.proxy!.$el.getBoundingClientRect().left
    // container width
    const offsetWidth = instance!.proxy!.$el.offsetWidth
    // left boundary
    const maxLeft = offsetWidth - menuMinWidth
    // 15: margin right
    const left15 = e.clientX - offsetLeft + 15
    if (left15 > maxLeft) {
        left.value = maxLeft
    } else {
        left.value = left15
    }
    top.value = e.clientY
    visible.value = true
    selectedTag.value = tag
}

const closeMenu = () => {
    visible.value = false
}

watch(
    route,
    () => {
        addTags()
    },
    {
        deep: true
    }
)



onMounted(() => {
    initTags()
    addTags()
})



watch(visible, (value) => {
    if (value) {
        document.body.addEventListener("click", closeMenu)
    } else {
        document.body.removeEventListener("click", closeMenu)
    }
})

onMounted(async () => {
    initTags()
    addTags()


    // 监听路由改变事件
    bus.on('routerUpdate', (title: string) => {
        let oldRouterList = [...tagsViewStore.visitedViews]
        let index = oldRouterList.findIndex(item => item?.meta?.title === title)
        // 如果是新增路由为原来路由list长度
        tagValue.value = index === -1 ? oldRouterList.length : index
    })

})



const showTagIcon = computed(() => settingsStore.showTagIcon)


const updateValue = (value: any) => tagValue.value = value


</script>

<style lang="scss" scoped>
.tags-view-container {
    height: var(--v3-tagsview-height);
    width: 100%;
    background-color: #fff;
    border-bottom: 1px solid #d8dce5;
    box-shadow: 0 1px 3px 0 #00000010, 0 0 3px 0 #00000010;
    overflow: auto hidden !important;
    white-space: nowrap;



    .tags-view-wrapper {
        display: flex;
        justify-content: left;
        align-items: center;

        .tags-view-item {
            display: inline-flex;
            justify-content: center;
            align-items: center;
            position: relative;
            cursor: pointer;
            height: 36px;
            //line-height: 26px;
            // border: 1px solid var(--v3-tagsview-tag-border-color);
            // border-radius: var(--v3-tagsview-tag-border-radius);
            color: var(--v3-tagsview-tag-text-color);
            background-color: var(--v3-tagsview-tag-bg-color);
            padding: 0 10px;
            font-size: 14px;
            margin-left: 5px;
            margin-top: 4px;

            &:first-of-type {
                margin-left: 5px;
            }

            &:last-of-type {
                margin-right: 5px;
            }

            &.active {
                background-color: var(--v3-tagsview-tag-active-bg-color);
                color: var(--v3-tagsview-tag-active-text-color);
                border-color: var(--v3-tagsview-tag-active-border-color);

                // &::before {
                //     content: "";
                //     background-color: var(--v3-tagsview-tag-active-before-color);
                //     display: inline-block;
                //     width: 8px;
                //     height: 8px;
                //     border-radius: 50%;
                //     position: relative;
                //     margin-right: 2px;
                // }
            }

            .v-icon {
                margin: 0 2px;
                vertical-align: middle;
                border-radius: 50%;

                &:hover {
                    background-color: var(--v3-tagsview-tag-icon-hover-bg-color);
                    color: var(--v3-tagsview-tag-icon-hover-color);
                }
            }
        }
    }

    .contextmenu {
        margin: 0;
        background-color: #fff;
        z-index: 3000;
        position: absolute;
        list-style-type: none;
        padding: 5px 0;
        border-radius: 4px;
        font-size: 12px;
        font-weight: 400;
        color: #333;
        box-shadow: 2px 2px 3px 0 #00000030;

        li {
            margin: 0;
            padding: 7px 16px;
            cursor: pointer;

            &:hover {
                background-color: #eee;
            }
        }
    }
}
</style>
